import {
  Camera,
  Group,
  Mesh,
  Object3DEventMap,
  ShaderChunk,
  Vector3,
  Vector3Tuple,
} from "three";

/**
 * 为模型的网格启用阴影
 * @param scene 模型的根节点
 */
export function openShadow(scene: Group<Object3DEventMap>) {
  scene.traverse(
    (obj) => obj instanceof Mesh && (obj.receiveShadow = obj.castShadow = true)
  );
}

/**
 * 将Vector3 转换为 Vector3Tuple
 */
export const vectorToTuple = (vector: {
  x: number;
  y: number;
  z: number;
}): Vector3Tuple => [vector.x, vector.y, vector.z];

/**
 * 添加自定义的 色调映射函数
 */
export function addCustomTone() {
  ShaderChunk.tonemapping_pars_fragment =
    ShaderChunk.tonemapping_pars_fragment.replace(
      "vec3 CustomToneMapping( vec3 color ) { return color; }",
      `float startCompression = 0.8 - 0.04;
       float desaturation = 0.15;
       vec3 CustomToneMapping( vec3 color ) {
         color *= toneMappingExposure;
         float x = min(color.r, min(color.g, color.b));
         float offset = x < 0.08 ? x - 6.25 * x * x : 0.04;
         color -= offset;
         float peak = max(color.r, max(color.g, color.b));
         if (peak < startCompression) return color;
         float d = 1. - startCompression;
         float newPeak = 1. - d * d / (peak + d - startCompression);
         color *= newPeak / peak;
         float g = 1. - 1. / (desaturation * (peak - newPeak) + 1.);
         return mix(color, vec3(1, 1, 1), g);
       }`
    );
}

/**
 * 获取当前相机的看向的位置
 */
export const cameraLookPos = (camera: Camera) =>
  camera.getWorldDirection(new Vector3()).add(camera.position);
